﻿using PhoneStoreWeb.Models;
using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace PhoneStoreWeb.Controllers
{
    public class ShoppingCartController : Controller
    {
        static PhoneStoreEntities storeDB = new PhoneStoreEntities();

        public ViewResult Index()
        {
            // Create | Get ShoppingCartModel instance
            var cartModel = ShoppingCartModel.GetCart(this.HttpContext);
            // Get all products from this cart
            var cartItems = storeDB.Carts.Where(c => c.CartID == cartModel.ShoppingCartId);
            ShoppingCartViewModel shoppingCartViewModel = new ShoppingCartViewModel
            {
                CartItems = cartItems.ToList(),
                CartTotal = GetTotalPrice(cartModel)
            };
            return View(shoppingCartViewModel);
        }
        
        [HttpPost]
        public RedirectToRouteResult Index(ShoppingCartViewModel model)
        {
            if (ModelState.IsValid)
            {
                int id = 0;
                // Create | Get ShoppingCartModel instance
                var cartModel = ShoppingCartModel.GetCart(this.HttpContext);
                // Get all products from this cart
                var cartItems = storeDB.Carts.Where(c => c.CartID == cartModel.ShoppingCartId);
                foreach (var cartItem in cartItems)
                {
                    cartItem.Quantity = model.CartItems[id++].Quantity;
                }
                storeDB.SaveChanges();
            }
            return RedirectToAction("Index");
        }

        // id: ProductID
        public RedirectToRouteResult AddToCart(int id)
        {
            var product = storeDB.Products.FirstOrDefault(p => p.ProductID == id);
            ShoppingCartModel cart = ShoppingCartModel.GetCart(this.HttpContext);
            // Add a record to Cart table or update product's quantity
            var cartItem = storeDB.Carts.FirstOrDefault(c => c.CartID == cart.ShoppingCartId && c.ProductID == product.ProductID);
            if (cartItem == null) // Add new
            {
                cartItem = new Cart
                {
                    CartID = cart.ShoppingCartId,
                    Quantity = 1,
                    CreatedDate = DateTime.Now,
                    ProductID = product.ProductID
                };
                storeDB.Carts.Add(cartItem);
            }
            else
            {
                // This product already exists in cart, so increase its quantity
                cartItem.Quantity++;
            }
            storeDB.SaveChanges();
            return RedirectToAction("Index");
        }

        // id: RecordID
        public ActionResult RemoveFromCart(int id)
        {
            ShoppingCartModel cartModel = ShoppingCartModel.GetCart(this.HttpContext);
            var cartItem = storeDB.Carts.FirstOrDefault(c => c.RecordID == id);
            string productName;
            if (cartItem != null) // Remove a record from Cart table
            {
                productName = cartItem.Product.Name;
                storeDB.Carts.Remove(cartItem);
                storeDB.SaveChanges();
            }
            return RedirectToAction("Index");
        }

        private decimal GetTotalPrice(ShoppingCartModel cartModel)
        {
            // Get all products from this cart
            var cartItems = storeDB.Carts.Where(c => c.CartID == cartModel.ShoppingCartId);
            // Get sum of all products' price in this cart
            decimal total = 0;
            foreach (var cartItem in cartItems)
            {
                if (!cartItem.Product.IsPromotional)
                {
                    total += cartItem.Quantity * cartItem.Product.RetailPrice;
                }
                else
                {
                    int newPrice = (int)cartItem.Product.RetailPrice * (100 - (int)cartItem.Product.Promotions.Last(p => p.ProductID == cartItem.ProductID).Percentage) / 100;
                    total += cartItem.Quantity * newPrice;
                }
            }
            return total;
        }

        // Get all products in this cart
        public static int GetTotalProducts(ShoppingCartModel cartModel)
        {
            int totalProducts = storeDB.Carts.Where(c => c.CartID == cartModel.ShoppingCartId).Count();
            return totalProducts;
        }

        [ChildActionOnly]
        public ActionResult CartSummary()
        {
            var cartModel = ShoppingCartModel.GetCart(this.HttpContext);
            ViewBag.CartCount = GetTotalProducts(cartModel);
            return PartialView("CartSummary");
        }

        public static void EmptyCart(HttpContextBase context)
        {
            // Create | Get ShoppingCartModel instance
            var cartModel = ShoppingCartModel.GetCart(context);
            var cartItems = storeDB.Carts.Where(c => c.CartID == cartModel.ShoppingCartId);
            foreach (var cartItem in cartItems)
            {
                storeDB.Carts.Remove(cartItem);
            }
            storeDB.SaveChanges();
        }

        // Delete all products from this cart
        public RedirectToRouteResult EmptyCart()
        {
            EmptyCart(this.HttpContext);
            return RedirectToAction("Index");
        }

        // Migration
        public static void MigrateCart(HttpContextBase context, string username)
        {
            // Create | Get ShoppingCartModel instance
            var cartModel = ShoppingCartModel.GetCart(context);
            var cartItems = storeDB.Carts.Where(c => c.CartID == cartModel.ShoppingCartId);
            foreach (var cartItem in cartItems)
            {
                cartItem.CartID = username;
            }
            storeDB.SaveChanges();
        }
    }
}